// Service Worker 管理模块
import envConfig from '../../../env.config.js';

/**
 * Service Worker 管理器
 * 提供模块化的 Service Worker 管理功能，解决无限刷新问题
 */
class ServiceWorkerManager {
  constructor() {
    // 实例化标记，防止重复初始化
    this.initialized = false;
    // 防止无限刷新的计数器
    this.reloadCounter = 0;
    this.maxReloads = 3;
    // 上次刷新时间戳
    this.lastReloadTime = 0;
    this.minReloadInterval = 5000; // 5秒内不允许重复刷新
  }

  /**
   * 初始化 Service Worker 管理器
   */
  async init() {
    if (this.initialized) {
      console.warn('Service Worker管理器已经初始化');
      return;
    }

    this.initialized = true;
    
    // 检查是否支持 Service Worker
    if (!('serviceWorker' in navigator)) {
      console.warn('浏览器不支持Service Worker');
      return;
    }

    // 检查是否应该启用 Service Worker
    if (!envConfig.serviceWorkerEnabled) {
      console.log('当前环境不启用Service Worker');
      // 在开发环境下注销所有已有的Service Worker
      if (envConfig.isDevelopment) {
        await this.unregisterAllServiceWorkers();
      }
      return;
    }

    try {
      // 注册 Service Worker
      const registration = await navigator.serviceWorker.register('/sw.js');
      console.log('Service Worker 注册成功:', registration);
      
      // 设置更新检查
      this.setupUpdateCheck(registration);
      // 设置更新按钮
      this.setupUpdateButton();
      
      return registration;
    } catch (error) {
      console.error('Service Worker注册失败:', error);
      throw error;
    }
  }

  /**
   * 设置更新检查
   */
  setupUpdateCheck(registration) {
    // 添加同步结果处理
    navigator.serviceWorker.addEventListener('message', this.handleMessage.bind(this));
    
    // 监听更新发现
    registration.addEventListener('updatefound', () => {
      const newWorker = registration.installing;
      
      newWorker.addEventListener('statechange', () => {
        if (newWorker.state === 'installed') {
          if (navigator.serviceWorker.controller) {
            console.log('发现新的应用版本，等待更新');
            this.showUpdatePrompt();
          } else {
            console.log('首次安装Service Worker');
            this.updateStatus('应用已缓存，可离线使用');
          }
        }
      });
    });

    // 控制器变化处理
    navigator.serviceWorker.addEventListener('controllerchange', this.handleControllerChange.bind(this));
  }

  /**
   * 处理消息事件
   */
  handleMessage(event) {
    if (event.data && event.data.type === 'SYNC_RESULTS') {
      this.handleSyncResults(event.data.data);
    }
  }

  /**
   * 处理控制器变化事件
   * 增强的控制器变化处理，防止无限刷新
   */
  handleControllerChange() {
    const now = Date.now();
    
    // 检查是否在短时间内重复刷新
    if (now - this.lastReloadTime < this.minReloadInterval) {
      console.warn('检测到短时间内频繁刷新，阻止无限刷新循环');
      this.updateStatus('检测到潜在的无限刷新问题，已阻止自动刷新');
      return;
    }
    
    // 检查刷新次数
    if (this.reloadCounter >= this.maxReloads) {
      console.warn(`已达到最大刷新次数(${this.maxReloads})，阻止无限刷新循环`);
      this.updateStatus('已达到最大刷新次数，防止无限刷新');
      return;
    }
    
    // 仅在生产环境下自动刷新页面
    if (!envConfig.isDevelopment) {
      console.log('Service Worker已更新，准备刷新页面');
      // 增加刷新计数器
      this.reloadCounter++;
      // 更新上次刷新时间
      this.lastReloadTime = now;
      // 使用setTimeout避免过于频繁的刷新
      setTimeout(() => {
        window.location.reload();
      }, 1000);
    }
  }

  /**
   * 显示更新提示
   */
  showUpdatePrompt() {
    const updatePrompt = document.getElementById('updatePrompt');
    if (updatePrompt) {
      updatePrompt.style.display = 'block';
    }
  }

  /**
   * 设置更新按钮
   */
  setupUpdateButton() {
    const updateButton = document.getElementById('updateButton');
    if (updateButton) {
      updateButton.addEventListener('click', () => {
        if (navigator.serviceWorker.controller) {
          console.log('触发应用更新');
          navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' });
          
          const updatePrompt = document.getElementById('updatePrompt');
          if (updatePrompt) {
            updatePrompt.innerHTML = '<p>更新中...</p>';
          }
        }
      });
    }
  }

  /**
   * 清除所有缓存
   */
  async clearAllCaches() {
    if (!('caches' in window)) {
      console.warn('浏览器不支持Cache API');
      return;
    }

    try {
      const cacheKeys = await caches.keys();
      await Promise.all(cacheKeys.map(key => caches.delete(key)));
      console.log('缓存已清除');
      this.updateStatus('缓存已清除，刷新页面...');
      
      // 使用setTimeout避免立即刷新导致的问题
      setTimeout(() => window.location.reload(), 1000);
    } catch (error) {
      console.error('清除缓存失败:', error);
    }
  }

  /**
   * 注销所有Service Worker
   */
  async unregisterAllServiceWorkers() {
    if (!('serviceWorker' in navigator)) {
      return;
    }

    try {
      const registrations = await navigator.serviceWorker.getRegistrations();
      await Promise.all(registrations.map(registration => registration.unregister()));
      console.log('已注销所有Service Worker');
    } catch (error) {
      console.error('注销Service Worker失败:', error);
    }
  }

  /**
   * 请求后台同步
   */
  async requestBackgroundSync(tag = 'apiQueue') {
    if (!('serviceWorker' in navigator && 'SyncManager' in window)) {
      console.warn('浏览器不支持后台同步功能');
      return Promise.reject(new Error('浏览器不支持后台同步功能'));
    }

    try {
      const registration = await navigator.serviceWorker.ready;
      await registration.sync.register(tag);
      console.log(`后台同步请求已注册: ${tag}`);
      this.updateStatus(`后台同步请求已注册，网络恢复时将自动同步`);
    } catch (error) {
      console.error('注册后台同步请求失败:', error);
      throw error;
    }
  }

  /**
   * 处理同步结果
   */
  handleSyncResults(results) {
    console.log('收到同步结果:', results);
    
    if (results.type === 'dataSync') {
      if (results.success) {
        this.updateStatus(results.message || '数据同步成功');
      } else {
        this.updateStatus('数据同步失败');
      }
      return;
    }
    
    // 处理API请求同步结果
    if (results.successful !== undefined || results.failed !== undefined) {
      let message = '';
      
      if (results.successful > 0 && results.failed === 0) {
        message = `所有 ${results.successful} 个请求同步成功`;
      } else if (results.successful > 0 && results.failed > 0) {
        message = `${results.successful} 个请求同步成功，${results.failed} 个请求同步失败`;
      } else if (results.failed > 0) {
        message = `所有 ${results.failed} 个请求同步失败，请稍后重试`;
      } else {
        message = '没有需要同步的请求';
      }
      
      this.updateStatus(message);
    }
  }

  /**
   * 更新状态显示
   */
  updateStatus(message) {
    const statusBar = document.getElementById('statusBar');
    if (statusBar) {
      statusBar.textContent = message;
    }
    
    // 如果没有状态栏，在控制台显示
    if (!statusBar && message) {
      console.log(`[PWA Status]: ${message}`);
    }
  }

  /**
   * 向Service Worker发送消息
   */
  async sendMessage(message) {
    if (!('serviceWorker' in navigator && navigator.serviceWorker.controller)) {
      console.warn('没有活跃的Service Worker');
      return Promise.reject(new Error('没有活跃的Service Worker'));
    }

    return new Promise((resolve, reject) => {
      // 创建消息通道
      const messageChannel = new MessageChannel();
      messageChannel.port1.onmessage = event => {
        if (event.data && event.data.error) {
          reject(new Error(event.data.error));
        } else {
          resolve(event.data);
        }
      };

      // 向Service Worker发送消息
      navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
    });
  }

  /**
   * 检查是否有更新可用
   */
  async checkForUpdates() {
    if (!('serviceWorker' in navigator)) {
      return false;
    }

    try {
      const registration = await navigator.serviceWorker.ready;
      if (registration.waiting) {
        // 已经有新版本等待激活
        this.showUpdatePrompt();
        return true;
      }
      
      // 强制检查更新
      if (registration.update) {
        await registration.update();
        console.log('已检查更新');
      }
      
      return false;
    } catch (error) {
      console.error('检查更新失败:', error);
      return false;
    }
  }
}

// 创建单例实例
const swManager = new ServiceWorkerManager();

// 导出管理器实例和便捷方法
export default swManager;

export const registerServiceWorker = () => swManager.init();
export const clearAllCaches = () => swManager.clearAllCaches();
export const unregisterAllServiceWorkers = () => swManager.unregisterAllServiceWorkers();
export const requestBackgroundSync = (tag) => swManager.requestBackgroundSync(tag);
export const updateStatus = (message) => swManager.updateStatus(message);
export const checkForUpdates = () => swManager.checkForUpdates();
export const sendMessageToSW = (message) => swManager.sendMessage(message);
